home *** CD-ROM | disk | FTP | other *** search
/ NeXT Education Software Sampler 1992 Fall / NeXT Education Software Sampler 1992 Fall.iso / Programming / Source / winterp-1.13 / src-server / xlisp / xlimage.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-04  |  11.0 KB  |  450 lines

  1. /* -*-C-*-
  2. ********************************************************************************
  3. *
  4. * File:         xlimage.c
  5. * RCS:          $Header: xlimage.c,v 1.7 91/03/24 22:24:52 mayer Exp $
  6. * Description:  xlisp memory image save/restore functions
  7. * Author:       David Michael Betz
  8. * Created:      
  9. * Modified:     Fri Oct  4 03:59:39 1991 (Niels Mayer) mayer@hplnpm
  10. * Language:     C
  11. * Package:      N/A
  12. * Status:       X11r5 contrib tape release
  13. *
  14. * WINTERP Copyright 1989, 1990, 1991 Hewlett-Packard Company (by Niels Mayer).
  15. * XLISP version 2.1, Copyright (c) 1989, by David Betz.
  16. *
  17. * Permission to use, copy, modify, distribute, and sell this software and its
  18. * documentation for any purpose is hereby granted without fee, provided that
  19. * the above copyright notice appear in all copies and that both that
  20. * copyright notice and this permission notice appear in supporting
  21. * documentation, and that the name of Hewlett-Packard and David Betz not be
  22. * used in advertising or publicity pertaining to distribution of the software
  23. * without specific, written prior permission.  Hewlett-Packard and David Betz
  24. * make no representations about the suitability of this software for any
  25. * purpose. It is provided "as is" without express or implied warranty.
  26. *
  27. * HEWLETT-PACKARD AND DAVID BETZ DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
  28. * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
  29. * IN NO EVENT SHALL HEWLETT-PACKARD NOR DAVID BETZ BE LIABLE FOR ANY SPECIAL,
  30. * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  31. * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  32. * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  33. * PERFORMANCE OF THIS SOFTWARE.
  34. *
  35. * See ./winterp/COPYRIGHT for information on contacting the authors.
  36. * Please send modifications, improvements and bugfixes to mayer@hplabs.hp.com
  37. * Post XLISP-specific questions/information to the newsgroup comp.lang.lisp.x
  38. *
  39. ********************************************************************************
  40. */
  41. static char rcs_identity[] = "@(#)$Header: xlimage.c,v 1.7 91/03/24 22:24:52 mayer Exp $";
  42.  
  43.  
  44. #include "xlisp.h"
  45.  
  46. #ifdef SAVERESTORE
  47.  
  48. /* external variables */
  49. extern LVAL obarray,xlenv,xlfenv,xldenv,s_gchook,s_gcflag;
  50. extern long nnodes,nfree,total;
  51. extern int anodes,nsegs,gccalls;
  52. extern struct segment *segs,*lastseg,*fixseg,*charseg;
  53. extern CONTEXT *xlcontext;
  54. extern LVAL fnodes;
  55.  
  56. /* local variables */
  57. static OFFTYPE off,foff,doff;
  58. static FILE *fp;
  59.  
  60. /* external procedures */
  61. extern SEGMENT *newsegment();
  62. extern FILE *osbopen();
  63. extern char *malloc();
  64.  
  65. /* forward declarations */
  66. OFFTYPE readptr();
  67. OFFTYPE cvoptr();
  68. LVAL cviptr();
  69.  
  70. /* xlisave - save the memory image */
  71. int xlisave(fname)
  72.   char *fname;
  73. {
  74.     char fullname[STRMAX+1];
  75.     unsigned char *cp;
  76.     SEGMENT *seg;
  77.     int n,i,max;
  78.     LVAL p;
  79.  
  80.     /* default the extension */
  81.     if (needsextension(fname)) {
  82.     strcpy(fullname,fname);
  83.     strcat(fullname,".wks");
  84.     fname = fullname;
  85.     }
  86.  
  87.     /* open the output file */
  88.     if ((fp = osbopen(fname,"w")) == NULL)
  89.     return (FALSE);
  90.  
  91.     /* first call the garbage collector to clean up memory */
  92.     gc();
  93.  
  94.     /* write out the pointer to the *obarray* symbol */
  95.     writeptr(cvoptr(obarray));
  96.  
  97.     /* setup the initial file offsets */
  98.     off = foff = (OFFTYPE)2;
  99.  
  100.     /* write out all nodes that are still in use */
  101.     for (seg = segs; seg != NULL; seg = seg->sg_next) {
  102.     p = &seg->sg_nodes[0];
  103.     for (n = seg->sg_size; --n >= 0; ++p, off += 2)
  104.         switch (ntype(p)) {
  105.         case FREE:
  106.         break;
  107.         case CONS:
  108.         case USTREAM:
  109.         setoffset();
  110.         osbputc(p->n_type,fp);
  111.         writeptr(cvoptr(car(p)));
  112.         writeptr(cvoptr(cdr(p)));
  113.         foff += 2;
  114.         break;
  115.         default:
  116.         setoffset();
  117.         writenode(p);
  118.         break;
  119.         }
  120.     }
  121.  
  122.     /* write the terminator */
  123.     osbputc(FREE,fp);
  124.     writeptr((OFFTYPE)0);
  125.  
  126.     /* write out data portion of vector-like nodes */
  127.     for (seg = segs; seg != NULL; seg = seg->sg_next) {
  128.     p = &seg->sg_nodes[0];
  129.     for (n = seg->sg_size; --n >= 0; ++p)
  130.         switch (ntype(p)) {
  131.         case SYMBOL:
  132.         case OBJECT:
  133.         case VECTOR:
  134.         case CLOSURE:
  135.         case STRUCT:
  136. #ifdef WINTERP
  137.         case XLTYPE_TIMEOUTOBJ:
  138.         case XLTYPE_CALLBACKOBJ:
  139.         case XLTYPE_EVHANDLEROBJ:
  140.         case XLTYPE_PIXMAP_REFOBJ:
  141.         case XLTYPE_WIDGETOBJ:
  142. #endif
  143.         max = getsize(p);
  144.         for (i = 0; i < max; ++i)
  145.             writeptr(cvoptr(getelement(p,i)));
  146.         break;
  147.         case STRING:
  148.         max = getslength(p);
  149.         for (cp = getstring(p); --max >= 0; )
  150.             osbputc(*cp++,fp);
  151.         break;
  152.         }
  153.     }
  154.  
  155.     /* close the output file */
  156.     osclose(fp);
  157.  
  158.     /* return successfully */
  159.     return (TRUE);
  160. }
  161.  
  162. /* xlirestore - restore a saved memory image */
  163. int xlirestore(fname)
  164.   char *fname;
  165. {
  166.     extern FUNDEF funtab[];
  167.     char fullname[STRMAX+1];
  168.     unsigned char *cp;
  169.     int n,i,max,type;
  170.     SEGMENT *seg;
  171.     LVAL p;
  172.  
  173.     /* default the extension */
  174.     if (needsextension(fname)) {
  175.     strcpy(fullname,fname);
  176.     strcat(fullname,".wks");
  177.     fname = fullname;
  178.     }
  179.  
  180.     /* open the file */
  181.     if ((fp = osbopen(fname,"r")) == NULL)
  182.     return (FALSE);
  183.  
  184.     /* free the old memory image */
  185.     freeimage();
  186.  
  187.     /* initialize */
  188.     off = (OFFTYPE)2;
  189.     total = nnodes = nfree = 0L;
  190.     fnodes = NIL;
  191.     segs = lastseg = NULL;
  192.     nsegs = gccalls = 0;
  193.     xlenv = xlfenv = xldenv = s_gchook = s_gcflag = NIL;
  194.     xlstack = xlstkbase + EDEPTH;
  195.     xlcontext = NULL;
  196.  
  197.     /* create the fixnum segment */
  198.     if ((fixseg = newsegment(SFIXSIZE)) == NULL)
  199.     xlfatal("insufficient memory - fixnum segment");
  200.  
  201.     /* create the character segment */
  202.     if ((charseg = newsegment(CHARSIZE)) == NULL)
  203.     xlfatal("insufficient memory - character segment");
  204.  
  205.     /* read the pointer to the *obarray* symbol */
  206.     obarray = cviptr(readptr());
  207.  
  208.     /* read each node */
  209.     while ((type = osbgetc(fp)) >= 0)
  210.     switch (type) {
  211.     case FREE:
  212.         if ((off = readptr()) == (OFFTYPE)0)
  213.         goto done;
  214.         break;
  215.     case CONS:
  216.     case USTREAM:
  217.         p = cviptr(off);
  218.         p->n_type = type;
  219.         p->n_flags = 0;
  220.         rplaca(p,cviptr(readptr()));
  221.         rplacd(p,cviptr(readptr()));
  222.         off += 2;
  223.         break;
  224.     default:
  225.         readnode(type,cviptr(off));
  226.         off += 2;
  227.         break;
  228.     }
  229. done:
  230.  
  231.     /* read the data portion of vector-like nodes */
  232.     for (seg = segs; seg != NULL; seg = seg->sg_next) {
  233.     p = &seg->sg_nodes[0];
  234.     for (n = seg->sg_size; --n >= 0; ++p)
  235.         switch (ntype(p)) {
  236.         case SYMBOL:
  237.         case OBJECT:
  238.         case VECTOR:
  239.         case CLOSURE:
  240.         case STRUCT:
  241. #ifdef WINTERP
  242.         case XLTYPE_TIMEOUTOBJ:
  243.         case XLTYPE_CALLBACKOBJ:
  244.             case XLTYPE_PIXMAP_REFOBJ:
  245.         case XLTYPE_WIDGETOBJ:
  246.         case XLTYPE_EVHANDLEROBJ:
  247. #endif
  248.         max = getsize(p);
  249.         if ((p->n_vdata = (LVAL *)malloc(max * sizeof(LVAL))) == NULL)
  250.             xlfatal("insufficient memory - vector");
  251.         total += (long)(max * sizeof(LVAL));
  252.         for (i = 0; i < max; ++i)
  253.             setelement(p,i,cviptr(readptr()));
  254.         break;
  255.         case STRING:
  256.         max = getslength(p);
  257.         if ((p->n_string = (unsigned char *)malloc(max)) == NULL)
  258.             xlfatal("insufficient memory - string");
  259.         total += (long)max;
  260.         for (cp = getstring(p); --max >= 0; )
  261.             *cp++ = osbgetc(fp);
  262.         break;
  263.         case STREAM:
  264. #if (defined(UNIX) || defined(WINTERP))
  265.         case XLTYPE_PIPE:
  266. #endif /* (defined(UNIX) || defined(WINTERP)) */
  267.         setfile(p,NULL);
  268.         break;
  269.         case SUBR:
  270.         case FSUBR:
  271.         p->n_subr = funtab[getoffset(p)].fd_subr;
  272.         break;
  273.         }
  274.     }
  275.  
  276.     /* close the input file */
  277.     osclose(fp);
  278.  
  279.     /* collect to initialize the free space */
  280.     gc();
  281.  
  282.     /* lookup all of the symbols the interpreter uses */
  283.     xlsymbols();
  284.  
  285.     /* return successfully */
  286.     return (TRUE);
  287. }
  288.  
  289. /* freeimage - free the current memory image */
  290. LOCAL freeimage()
  291. {
  292.     SEGMENT *seg,*next;
  293.     FILE *fp;
  294.     LVAL p;
  295.     int n;
  296.  
  297.     /* free the data portion of vector-like nodes */
  298.     for (seg = segs; seg != NULL; seg = next) {
  299.     p = &seg->sg_nodes[0];
  300.     for (n = seg->sg_size; --n >= 0; ++p)
  301.         switch (ntype(p)) {
  302.         case SYMBOL:
  303.         case OBJECT:
  304.         case VECTOR:
  305.         case CLOSURE:
  306.         case STRUCT:
  307. #ifdef WINTERP
  308.         case XLTYPE_TIMEOUTOBJ:
  309.         case XLTYPE_CALLBACKOBJ:
  310.             case XLTYPE_PIXMAP_REFOBJ:
  311.         case XLTYPE_WIDGETOBJ:
  312.         case XLTYPE_EVHANDLEROBJ:
  313. #endif
  314.         if (p->n_vsize)
  315.             free(p->n_vdata);
  316.         break;
  317.         case STRING:
  318.         if (getslength(p))
  319.             free(getstring(p));
  320.         break;
  321.         case STREAM:
  322.         if ((fp = getfile(p)) && (fp != stdin && fp != stdout && fp != stderr))
  323.             osclose(getfile(p));
  324.         break;
  325. #if (defined(UNIX) || defined(WINTERP))
  326.         case XLTYPE_PIPE:
  327.         if (fp = getfile(p))
  328.             pclose(getfile(p));
  329.         break;
  330. #endif /* (defined(UNIX) || defined(WINTERP)) */
  331.         }
  332.     next = seg->sg_next;
  333.     free(seg);
  334.     }
  335. }
  336.  
  337. /* setoffset - output a positioning command if nodes have been skipped */
  338. LOCAL setoffset()
  339. {
  340.     if (off != foff) {
  341.     osbputc(FREE,fp);
  342.     writeptr(off);
  343.     foff = off;
  344.     }
  345. }
  346.  
  347. /* writenode - write a node to a file */
  348. LOCAL writenode(node)
  349.   LVAL node;
  350. {
  351.     char *p = (char *)&node->n_info;
  352.     int n = sizeof(union ninfo);
  353.     osbputc(node->n_type,fp);
  354.     while (--n >= 0)
  355.     osbputc(*p++,fp);
  356.     foff += 2;
  357. }
  358.  
  359. /* writeptr - write a pointer to a file */
  360. LOCAL writeptr(off)
  361.   OFFTYPE off;
  362. {
  363.     char *p = (char *)&off;
  364.     int n = sizeof(OFFTYPE);
  365.     while (--n >= 0)
  366.     osbputc(*p++,fp);
  367. }
  368.  
  369. /* readnode - read a node */
  370. LOCAL readnode(type,node)
  371.   int type; LVAL node;
  372. {
  373.     char *p = (char *)&node->n_info;
  374.     int n = sizeof(union ninfo);
  375.     node->n_type = type;
  376.     node->n_flags = 0;
  377.     while (--n >= 0)
  378.     *p++ = osbgetc(fp);
  379. }
  380.  
  381. /* readptr - read a pointer */
  382. LOCAL OFFTYPE readptr()
  383. {
  384.     OFFTYPE off;
  385.     char *p = (char *)&off;
  386.     int n = sizeof(OFFTYPE);
  387.     while (--n >= 0)
  388.     *p++ = osbgetc(fp);
  389.     return (off);
  390. }
  391.  
  392. /* cviptr - convert a pointer on input */
  393. LOCAL LVAL cviptr(o)
  394.   OFFTYPE o;
  395. {
  396.     OFFTYPE off = (OFFTYPE)2;
  397.     SEGMENT *seg;
  398.  
  399.     /* check for nil */
  400.     if (o == (OFFTYPE)0)
  401.     return ((LVAL)o);
  402.  
  403.     /* compute a pointer for this offset */
  404.     for (seg = segs; seg != NULL; seg = seg->sg_next) {
  405.     if (o >= off && o < off + (OFFTYPE)(seg->sg_size << 1))
  406.         return (seg->sg_nodes + ((int)(o - off) >> 1));
  407.     off += (OFFTYPE)(seg->sg_size << 1);
  408.     }
  409.  
  410.     /* create new segments if necessary */
  411.     for (;;) {
  412.  
  413.     /* create the next segment */
  414.     if ((seg = newsegment(anodes)) == NULL)
  415.         xlfatal("insufficient memory - segment");
  416.  
  417.     /* check to see if the offset is in this segment */
  418.     if (o >= off && o < off + (OFFTYPE)(seg->sg_size << 1))
  419.         return (seg->sg_nodes + ((int)(o - off) >> 1));
  420.     off += (OFFTYPE)(seg->sg_size << 1);
  421.     }
  422. }
  423.  
  424. /* cvoptr - convert a pointer on output */
  425. LOCAL OFFTYPE cvoptr(p)
  426.   LVAL p;
  427. {
  428.     OFFTYPE off = (OFFTYPE)2;
  429.     SEGMENT *seg;
  430.  
  431.     /* check for nil and small fixnums */
  432.     if (p == NIL)
  433.     return ((OFFTYPE)p);
  434.  
  435.     /* compute an offset for this pointer */
  436.     for (seg = segs; seg != NULL; seg = seg->sg_next) {
  437.     if (CVPTR(p) >= CVPTR(&seg->sg_nodes[0]) &&
  438.         CVPTR(p) <  CVPTR(&seg->sg_nodes[0] + seg->sg_size))
  439.         return (off + (OFFTYPE)((p - seg->sg_nodes) << 1));
  440.     off += (OFFTYPE)(seg->sg_size << 1);
  441.     }
  442.  
  443.     /* pointer not within any segment */
  444.     xlerror("bad pointer found during image save",p);
  445. }
  446.  
  447. #endif
  448.  
  449.